<script setup>
import {ref, reactive, toRefs} from 'vue'
import useMainStore from '@/store/main'
import {notificationMess} from '@/utils/message'
import deepClone from '@/utils/deepClone'
import {checkNullObj} from '@/utils/check-obj'

//接收参数
const props = defineProps({
  changeConfig: {type: Object},
  showType: {
    type: String,
    default: 'dialog',
    validator: (val) => ['dialog', 'drawer'].includes(val)
  },
  newFn: {type: Function},
  editFn: {type: Function},
  beforeNewCallback: {type: Function},
  newCancelCallback: {type: Function}
})

//判断展示类型
const cpnType = props.showType === 'dialog' ? 'el-dialog' : 'el-drawer'

//提取设置
const changeConfig = reactive(props.changeConfig)
const {table, title, formSlotNames, formConfig, afterConfig} = toRefs(changeConfig)

//初始数据
const defaultProp = {}
formConfig.value.forEach((item) => defaultProp[item.prop] = '')

//表单数据
const form = ref(defaultProp)

//是否是新建
const isNew = ref(true)

//弹出层状态
const isShow = ref(false)

//编辑表单事件
const setForm = (key, value) => {
  //打开弹出层
  form.value[key] = value
}

//打开弹出层
const open = (formData) => {
  //判断id是否存在
  isNew.value = formData?._id === undefined
  //赋值表单
  form.value = deepClone(formData)
  //显示弹出层
  isShow.value = true
}

//确定事件
const mainStore = useMainStore()
const handleConfirm = async () => {
  //提取数据
  const {_id, ...formValue} = form.value
  //关闭弹出层
  isShow.value = false

  //定义执行函数
  const newFn = props.newFn ? props.newFn : mainStore.fetchAddAction
  const editFn = props.editFn ? props.editFn : mainStore.fetchEditAction

  //编辑数据库
  isNew.value ? await newFn(table.value, formValue, afterConfig?.value?.addAfterFetchData)
    : await editFn(table.value, _id, formValue, afterConfig?.value?.editAfterFetchData)
}

//关闭回调
const handleCancel = () => isShow.value = false

//关闭弹出层前的事件
const handleBeforeClose = (done) => {
  //如果是新建则执行新建前回调
  if (isNew.value && props.beforeNewCallback) return props.beforeNewCallback(done)

  //关闭弹出层
  done()
}

//关闭弹出层事件
const handleClose = () => {
  //如果是新建则执行新建后回调
  if (isNew.value && props.newCancelCallback) props.newCancelCallback()
}

//暴露事件
defineExpose({open, setForm})
</script>

<template>
  <component :is="cpnType" v-model="isShow" :title="title" width="30%" center :before-close="handleBeforeClose"
             @close="handleClose">
    <!-- 表单 -->
    <app-form v-model="form" :form-config="formConfig" @cancel="handleBeforeClose(handleCancel)"
              @confirm="handleConfirm">
      <template #[item]="scope" v-for="item in formSlotNames" :key="item">
        <slot :name="item" v-bind="scope"/>
      </template>
    </app-form>
  </component>
</template>

<style lang="scss" scoped>
.page-dialog {
}
</style>
